package com.tanhua.server.service;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import cn.hutool.json.JSONUtil;
import com.tanhua.common.service.PicUploadService;
import com.tanhua.common.utils.UserThreadLocal;
import com.tanhua.common.vo.ErrorResult;
import com.tanhua.common.vo.PicUploadResult;
import com.tanhua.dubbo.api.*;
import com.tanhua.dubbo.pojo.*;
import com.tanhua.dubbo.vo.PageInfo;
import com.tanhua.server.vo.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.factory.annotation.Autowired;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;


import java.util.*;
import java.util.stream.Collectors;


import static com.tanhua.server.service.SmsService.REDIS_CODE;
import static org.bouncycastle.asn1.x500.style.RFC4519Style.uid;

/**
 * @author zmy12345
 */
@Service
@Slf4j
public class MyCenterService {

    @DubboReference(version = "1.0.0")
    private UserInfoApi userInfoApi;

    @DubboReference(version = "1.0.0")
    private RecommendUserApi recommendUserApi;

    @DubboReference(version = "1.0.0")
    private UserLikeApi userLikeApi;
    @DubboReference(version = "1.0.0")
    private VisitorsApi visitorsApi;

    @Autowired
    private IMService imService;

    @DubboReference(version = "1.0.0")
    private UserApi userApi;

    @DubboReference(version = "1.0.0")
    private QuestionApi questionApi;

    @DubboReference(version = "1.0.0")
    private BlackListApi blackListApi;

    @DubboReference(version = "1.0.0")
    private SettingsApi settingsApi;

    @Autowired
    private PicUploadService picUploadService;

    @Autowired
    private StringRedisTemplate redisTemplate;

    @Autowired
    private RocketMQTemplate rocketMQTemplate;

    @Autowired
    private SmsService smsService;

    @Autowired
    private TanHuaService tanHuaService;

    private static final String REDIS_CODE_CHANGEPHONE = "REDIS_CODE_CHAGEPHONE_";

    public UserInfoVo queryUserInfoByUserId(Long userId) {
        if (null == userId) {
            userId = UserThreadLocal.get();
        }

        //根据用户id查询用户信息
        UserInfo userInfo = this.userInfoApi.queryByUserId(userId);

        //封装UserInfoVo
        UserInfoVo userInfoVo = BeanUtil.toBeanIgnoreError(userInfo, UserInfoVo.class);
        userInfoVo.setGender(userInfo.getSex().name().toLowerCase());
        userInfoVo.setMarriage(StrUtil.equals("已婚", userInfo.getMarriage()) ? 1 : 0);
        return userInfoVo;
    }

    /**
     * 是否喜欢
     *
     * @param userId
     * @return
     */
    public Boolean isLike(Long userId) {
        return this.userLikeApi.isLike(UserThreadLocal.get(), userId);
    }

    /**
     * 查询互相喜欢、喜欢、粉丝、谁看过我 - 翻页列表
     *
     * @param page
     * @param pageSize
     * @param nickname
     * @param type
     * @return
     */
    public Object queryLikeList(Integer page, Integer pageSize, String nickname, String type) {
        PageResult pageResult = new PageResult();
        pageResult.setPage(page);
        pageResult.setPagesize(pageSize);
        Long userId = UserThreadLocal.get();

        List<Object> userIdList = Collections.emptyList();

        if (nickname == null) {

            // 1互相关注  2我关注  3粉丝  4谁看过我
            switch (type) {
                case "1": {

                    PageInfo<UserLike> pageInfo = this.userLikeApi.queryMutualLikeList(userId, page, pageSize + 2);
                    List<UserLike> records = pageInfo.getRecords();
                    userIdList = CollUtil.getFieldValues(records, "userId");
                    break;
                }
                case "2": {
                    PageInfo<UserLike> pageInfo = this.userLikeApi.queryLikeList(userId, page, pageSize + 2);
                    List<UserLike> records = pageInfo.getRecords();
                    userIdList = CollUtil.getFieldValues(records, "likeUserId");
                    break;
                }
                case "3": {
                    PageInfo<UserLike> pageInfo = this.userLikeApi.queryFanList(userId, page, pageSize + 2);
                    List<UserLike> records = pageInfo.getRecords();
                    userIdList = CollUtil.getFieldValues(records, "userId");
                    break;
                }
                case "4": {
                    PageInfo<Visitors> pageInfo = this.visitorsApi.topVisitor(userId, page, pageSize + 2);
                    List<Visitors> records = pageInfo.getRecords();
                    userIdList = CollUtil.getFieldValues(records, "visitorUserId");
                    break;
                }
                default:
                    return pageResult;
            }

        } else {
            // 1互相关注  2我关注  3粉丝  4谁看过我
            switch (type) {
                case "1": {
                    List<UserLike> mutualLikeList = this.userLikeApi.queryMutualLikeList(userId);
                    userIdList = CollUtil.getFieldValues(mutualLikeList, "userId");
                    break;
                }
                case "2": {
                    List<UserLike> likeList = this.userLikeApi.queryLikeList2(userId);
                    userIdList = CollUtil.getFieldValues(likeList, "likeUserId");
                    break;
                }
                case "3": {
                    List<UserLike> fanList = this.userLikeApi.queryFanList(userId);
                    userIdList = CollUtil.getFieldValues(fanList, "userId");
                    break;
                }

                default:
                    return pageResult;
            }
        }

        if (CollUtil.isEmpty(userIdList)) {
            return pageResult;
        }

        Map<Long, UserInfo> userInfoMap = this.userInfoApi.queryMapByUserIdListAndNikeName(userIdList, nickname);

        List<UserLikeListVo> userLikeListVoList = new ArrayList<>();

        Set<Long> longs = userInfoMap.keySet();
        List<Long> uidList = new ArrayList<>();
        Iterator<Long> iterator = longs.iterator();
        while (iterator.hasNext()) {
            Long uid = iterator.next();
            uidList.add(uid);
        }
        for (Long uid : uidList) {
            Boolean like = this.userLikeApi.isLike(userId, Convert.toLong(uid));
            Double score = this.recommendUserApi.queryScore(userId, (Long) uid);
            UserLikeListVo userLikeListVo = BeanUtil.toBeanIgnoreError(userInfoMap.get(uid), UserLikeListVo.class);
            userLikeListVo.setNickname(userInfoMap.get(uid).getNickName());
            userLikeListVo.setAlreadyLove(like);
            userLikeListVo.setMatchRate(Convert.toInt(score));
            userLikeListVo.setId(userInfoMap.get(uid).getId());
            userLikeListVo.setGender(userInfoMap.get(uid).getSex().name().toLowerCase());
            userLikeListVo.setMarriage(ObjectUtil.equals(userInfoMap.get(uid).getMarriage(), "未婚") ? 0 : 1);
            userLikeListVo.setAlreadyLove(this.userLikeApi.isLike(userId, userInfoMap.get(uid).getUserId()));
            userLikeListVoList.add(userLikeListVo);
        }


        pageResult.setItems(userLikeListVoList);


        return pageResult;

    }

    /**
     * 取消喜欢
     *
     * @param likeUserId
     * @return
     */
    public void disLike(Long likeUserId) {
        Long userId = UserThreadLocal.get();
        //判断是否相互喜欢
        Boolean mutualLike = this.userLikeApi.isMutualLike(userId, likeUserId);
        //取消好友关系,取消在环信平台的好友关系
        if (mutualLike) {
            this.imService.removeUser(userId, likeUserId);
        }
        //取消喜欢
        this.userLikeApi.notLikeUser(userId, likeUserId);
    }

    /**
     * 粉丝,喜欢
     *
     * @param likeUserId
     */
    public void likeUser(Long likeUserId) {
        Long userId = UserThreadLocal.get();
        //添加到redis和MongoDB
        this.userLikeApi.likeUser(userId, likeUserId);
        //添加到好友关系
        this.tanHuaService.likeUser(likeUserId);

    }

    /**
     * 设置陌生人问题
     *
     * @param content
     * @return
     */
    public Object setQuestion(String content) {

        Long userId = UserThreadLocal.get();

        return 1 == this.questionApi.setQuestion(userId, content);

    }

    /**
     * 查询黑名单
     *
     * @param page
     * @param pageSize
     * @return
     */
    public Object queryBlacklist(Integer page, Integer pageSize) {
        Long userId = UserThreadLocal.get();
        //Long userId = 1L;

        PageResult pageResult = new PageResult();
        pageResult.setPage(page);
        pageResult.setPagesize(pageSize);
        pageResult.setPages(0);
        pageResult.setCounts(0);

        List<BlackList> blackLists = this.blackListApi.queryBlackList(userId, page, pageSize);
        if (CollUtil.isEmpty(blackLists)) {
            pageResult.setItems(Collections.emptyList());
            return pageResult;
        }
        List<Object> blackUserIdList = CollUtil.getFieldValues(blackLists, "blackUserId");

        Map<Long, UserInfo> userInfoMap = this.userInfoApi.queryMapByUserIdList(blackUserIdList);


        List<BlackListVo> blackListVoList = blackLists.stream().map(blackList -> {
            BlackListVo blackListVo = BeanUtil.toBeanIgnoreError(userInfoMap.get(blackList.getBlackUserId()), BlackListVo.class);
            blackListVo.setGender(ObjectUtil.equals(userInfoMap.get(blackList.getBlackUserId()).getSex(), "男") ? "man" : "woman");
            return blackListVo;
        }).collect(Collectors.toList());

        pageResult.setItems(blackListVoList);

        return pageResult;
    }

    /**
     * 删除黑名单
     *
     * @param uid
     * @return
     */
    public Object deleteBlackUser(String uid) {

        Long userId = UserThreadLocal.get();

        return this.blackListApi.deleteBlackUser(userId, uid);

    }


    /**
     * 发送短信
     *
     * @return
     */
    public Object sendVerificationCode() {

        Long userId = UserThreadLocal.get();

        User user = this.userApi.queryById(userId);
        String redisKey = REDIS_CODE_CHANGEPHONE + user.getMobile();

        String redisCode = this.redisTemplate.opsForValue().get(redisKey);
        if (redisCode != null) {
            String code = "123456";
            redisTemplate.opsForValue().set(redisKey, code);
            return null;
        }

        String code = this.smsService.sendSms(user.getMobile());
        code = "123456";
        log.debug("-----------------------------------{}", code);
        log.info("-----------------------------------{}", code);

        redisTemplate.opsForValue().set(redisKey, code);

        return null;

    }


    /**
     * 校验验证码
     *
     * @param verificationCode
     * @return
     */
    public Boolean checkVerificationCode(String verificationCode) {

        Long userId = UserThreadLocal.get();


        User user = this.userApi.queryById(userId);

        String redisKey = REDIS_CODE_CHANGEPHONE + user.getMobile();

        String rediscode = redisTemplate.opsForValue().get(redisKey);

        if (StrUtil.equals(rediscode, verificationCode)) {
            //校验通过
            log.debug("----------------verificationCode--{}-----------------------rediscode--{}", verificationCode, rediscode);
            return true;
        }
        return false;
    }

    /**
     * 修改手机号码
     *
     * @param phone
     * @return
     */
    public Object changePhone(String phone) {

        Long userId = UserThreadLocal.get();
        int result = this.userApi.updateUser(userId, phone);

        return 1 == result;
    }

    /**
     * settings
     *
     * @return
     */
    public Object settings() {
        Long userId = UserThreadLocal.get();


        User user = this.userApi.queryById(userId);
        Settings settings = this.settingsApi.queryById(userId);
        UserSettingsVo userSettingsVo = BeanUtil.toBeanIgnoreError(settings, UserSettingsVo.class);
        Question question = this.questionApi.queryQuestion(userId);
        if (ObjectUtil.isEmpty(question)) {
            return userSettingsVo;
        }
        userSettingsVo.setPhone(user.getMobile());
        if (ObjectUtil.isEmpty(question.getTxt())) {
            return userSettingsVo;
        }
        userSettingsVo.setStrangerQuestion(question.getTxt());

        return userSettingsVo;


    }

    public Object notificationsSetting(Object likeNotification, Object pinglunNotification, Object gonggaoNotification) {
        Long userId = UserThreadLocal.get();

        return 1 == this.settingsApi.notificationsSetting(userId, likeNotification, pinglunNotification, gonggaoNotification);


    }

    /**
     * 保存用户信息
     *
     * @param userInfovo
     * @return
     */
    public Object saveUserInfo(UserInfoVo userInfovo) {

        Long userId = UserThreadLocal.get();


        UserInfo userInfo = this.userInfoApi.queryByUserId(userId);
        if (userInfo == null) {
            System.out.println("haha");
        }
        BeanUtil.copyProperties(userInfovo, userInfo);

        Boolean result = this.userInfoApi.update(userInfo);

        if (result) {
            return null;
        }

        return ErrorResult
                .builder()
                .errCode("500")
                .errMessage("更新用户信息失败")
                .build();
    }

    /**
     * 修改用户头像
     *
     * @param headPhoto
     * @return
     */
    public Object saveHaeder(MultipartFile headPhoto) {
        Long userId = UserThreadLocal.get();
        UserInfo userInfo = this.userInfoApi.queryByUserId(userId);

        PicUploadResult upload = this.picUploadService.upload(headPhoto);

        if (upload == null) {
            return ErrorResult
                    .builder()
                    .errCode("500")
                    .errMessage("更新用户头像失败")
                    .build();
        }
        userInfo.setLogo(upload.getName());

        Boolean update = this.userInfoApi.update(userInfo);

        if (update) {
            return null;
        }

        return ErrorResult
                .builder()
                .errCode("500")
                .errMessage("更新用户头像失败")
                .build();
    }
}
